import React, {useState, useEffect, useMemo} from 'react';
import { to_float, obj_float, KInput, useKForm, WaitUmd, is_empty, Btn, obj_str, loc, PanelFind, Ret, Title, filter_row,
    d_sort, obj_int, uJob, for_obj, cline, InfoDlg, ck_float, useCmd, useHigh, GridTable } from 'sui';
import { sum_standout, get_col, reload, load_lub } from './cmd';
import { load_col_psn } from '../../task/psn/cmd';
import { DlgTask } from './ctl';
import { BindView } from './bind';

const PsnView = ({ cur, hreturn, no_acc }) => {
    const [sum, setSum] = useState([]);
    const [main, setMain] = useState();
    const [map_lub, mapLub] = useState();
    const [cur_num, curNum] = useState(0);
    const [row, setRow] = useState();
    const [open_info, openInfo] = useState(false);
    const [open_num, openNum] = useState(false);
    const [col, setCol] = useState();
    const [high] = useHigh(220, 100);
    const umd = useCmd();
    const form = useKForm(null, { w: 0.5 });

    useEffect(() => {
        load_col_psn(setCol);
        load_lub(mapLub);

        reload(null, (v) => {
            setMain(v);
            setRow(v);
            curNum(v ? v.length : 0);
            sum_standout(v, setSum);
        }, cur);
    }, [cur]);

    const getRange = (k1, k2) => {
        let min = form.get(k1);
        let max = form.get(k2);

        if (!min || !max) {
            return [false, null, null];
        }

        return [true, to_float(min), to_float(max)];
    };

    const isIn = (v, a, b) => {
        const kv = Math.trunc(v * 1000);
        const ka = Math.trunc(a * 1000);
        const kb = Math.trunc(b * 1000);

        return (kv >= ka && kv <= kb);
    };

    const ck_empty_float = (v, k1) => {
        const kv = form.get(k1);
        if (!v && !kv) {
            return null;
        }

        return ck_float(v);
    };

    const ck_range_float = (v, k1) => {
        const kv = form.get(k1);
        if (!v && !kv) {
            return null;
        }

        const a = to_float(kv);
        const b = to_float(v);

        if (b < a) {
            return loc("l_705");
        }
    };

    const hFind = (data) => {
        if (is_empty(data)) {
            setRow(null);
            curNum(0);
            return;
        }

        const ck = {
            dmin: v => ck_empty_float(v, "dmax"),
            dmax: v => ck_range_float(v, "dmin"),
            kmin: v => ck_empty_float(v, "kmax"),
            kmax: v => ck_range_float(v, "kmin"),
            bmin: v => ck_empty_float(v, "bmax"),
            bmax: v => ck_range_float(v, "bmin"),
            w: v => ck_empty_float(v, "w"),
        };

        if (form.isErr(ck)) {
            return;
        }

        const [is_dmin, dmin, dmax] = getRange("dmin", "dmax");
        const [is_kmin, kmin, kmax] = getRange("kmin", "kmax");
        const [is_bmin, bmin, bmax] = getRange("bmin", "bmax");
        const w = Math.trunc(to_float(form.get("w")) * 1000);

        let ret = data.filter(d => {
            const outwidth = obj_float(d, "outwidth");
            const inwidth = obj_float(d, "inwidth");

            let tmp = Math.abs(outwidth - inwidth);
            tmp = Math.trunc(tmp * 1000);

            return tmp <= w;
        });

        if (!is_dmin && !is_kmin && !is_bmin) {
            const val = [...data];
            d_sort(val, "boxgood");
            val.forEach((d, i) => d["index"] = i + 1);

            setRow(val);
            curNum(val ? val.length : 0);
            return;
        }

        ret = ret.filter(d => {
            const outdia = obj_float(d, "outdia");
            const india = obj_float(d, "india");
            const standout = obj_float(d, "standout");

            if (is_dmin && !isIn(outdia, dmin, dmax)) {
                return false;
            }

            if (is_kmin && !isIn(india, kmin, kmax)) {
                return false;
            }

            if (is_bmin && !isIn(standout, bmin, bmax)) {
                return false;
            }

            return true;
        });

        const set_india = {};

        ret.forEach(d => {
            const india = obj_str(d, "india");

            if (set_india[india]) {
                set_india[india].push(d);
            } else {
                set_india[india] = [d];
            }
        });

        const val = [];

        for_obj(set_india, (k, v) => {
            const set_standout = {};

            v.forEach(d => {
                const standout = obj_str(d, "standout");

                if (set_standout[standout]) {
                    set_standout[standout].push(d);
                } else {
                    set_standout[standout] = [d];
                }
            });

            for_obj(set_standout, (tk, tv) => {
                const num = tv.length - tv.length % 2;
                if (num <= 0) {
                    return;
                }

                for (let i = 0; i < num; i++) {
                    val.push(tv[i]);
                }
            });
        });

        d_sort(val, "boxgood");

        sum_standout(val, setSum);

        setRow(val);
        curNum(val ? val.length : 0);
    };

    const doTask = (val) => {
        if (is_empty(val)) {
            return;
        }

        umd.startWait();

        uJob(null, "goods/task",
            {
                line: cline(),
                k: obj_str(cur, "sn"),
                v: val,
            },
            r => {
                reload(null, (v) => {
                    setMain(v);
                    hFind(v);

                    umd.endWait();
                    openInfo(true);
                }, cur);
            },
            e => umd.setErr(), true);
    };

    const hBind = (v) => {
        umd.hreturn();
        doTask(v);
    };

    const getRow = useMemo(() => {
        if (is_empty(col)) {
            return null;
        }

        const lst = col.map(d => d.sn);
        return filter_row(row, lst, umd.filter);
    }, [row, umd.filter, col]);

    const getCol = useMemo(() => {
        return get_col(col, cur, map_lub);
    }, [col, map_lub, cur]);

    if (umd.isFin("bind")) {
        return <BindView hreturn={umd.hreturn} main={row} cur={cur} hcmd={hBind} col={getCol}/>;
    }

    const hOrder = (v) => {
        if (is_empty(row)) {
            return;
        }

        const dnum = obj_int(v, "dnum");
        const tmp = [];

        for (let i = 0; i < dnum; i++) {
            const d = row[i];
            tmp.push(d.sn);
        }

        doTask(tmp);
    };

    const sum_col = [
        {name: loc("l_748"), key: 'sn', width: 90},
        {name: loc("l_595"), key: 'val', width: 90},
    ];

    const Right = () => (
        <div className="inline-flex">
            <Btn hcmd={() => umd.pact(null, null, "bind")} color="teal" disabled={no_acc("na")}>{loc("l_865")}</Btn>
            <Btn className="ml-4" hcmd={() => openNum(true)} color="green" disabled={no_acc("na")}>{loc("l_854")}</Btn>
            <Ret className="ml-4" hcmd={hreturn}/>
        </div>
    );

    const Left = () => (
        <div className="inline-flex items-center">
            <Title mod={obj_str(cur, "sn")} sub={loc("l_152")}/>
            <div className="ml-10 bg-teal-300 px-3 pt-2 pb-1">{loc("l_127")}<span className="ml-6">{cur_num}</span></div>
        </div>
    );

    return (
        <div className="flex flex-col">
            <PanelFind left={<Left/>} right={<Right/>} hcmd={umd.setFilter}>
                <div className="inline-flex items-center mb-2">
                    <Btn className="mr-4" hcmd={() => hFind(main)} color="teal">{loc("l_832")}</Btn>
                    <div className="inline-flex items-center px-2 border-blue-600 border">
                        <span className="text-base mr-4 mt-1">{`${loc("l_690")} ( D )`}</span>
                        <KInput label={loc("l_696")} form={form} name="dmin" mg="dense" width="w-20"/>
                        <KInput label={loc("l_646")} form={form} name="dmax" mg="dense" width="w-20" className="ml-2"/>
                    </div>
                    <div className="inline-flex items-center px-2 ml-4 border-blue-600 border">
                        <span className="text-base mr-4 mt-1">{`${loc("l_691")} ( d )`}</span>
                        <KInput label={loc("l_696")} form={form} name="kmin" mg="dense" width="w-20"/>
                        <KInput label={loc("l_646")} form={form} name="kmax" mg="dense" width="w-20" className="ml-2"/>
                    </div>
                    <div className="inline-flex items-center px-2 ml-4 border-blue-600 border">
                        <span className="text-base mr-4 mt-1">{`${loc("l_743")} ( b )`}</span>
                        <KInput label={loc("l_696")} form={form} name="bmin" mg="dense" width="w-20"/>
                        <KInput label={loc("l_646")} form={form} name="bmax" mg="dense" width="w-20" className="ml-2"/>
                    </div>
                    <KInput label={loc("l_692")} form={form} name="w" mg="dense" width="w-24" className="ml-4"/>
                    <Btn className="ml-4" hcmd={() => form.clear_all()}>{loc("l_543")}</Btn>
                </div>
            </PanelFind>
            <GridTable high={high - 240} col={getCol} row={getRow}/>
            <div className="mt-4">
                <GridTable high={240} col={sum_col} row={sum}/>
            </div>
            <InfoDlg open={open_info} setOpen={openInfo} msg={loc("l_855")} hcmd={() => umd.endWait()}/>
            <DlgTask open={open_num} setOpen={openNum} hcmd={hOrder} data={{
                sn: obj_str(cur, "sn"),
                dnum: cur_num,
            }}/>
            <WaitUmd umd={umd}/>
        </div>
    );
};

export {PsnView};
